import React, { Component } from 'react'


/**
 * 注意：React并不会真正的绑定事件到每一个具体的元素上，而是采用事件代理的模式(绑在了根节点上，利用了事件流机制: 事件捕获 处于目标阶段 事件冒泡)
 */
export default class App extends Component {
    a = 100

    render() {
        return (
            <div>
                <input />
                {/* 能访问到 a */}
                <button onClick={() => { console.log('click1', '如果处理逻辑过多，不推荐这种写法', this.a); }}>add1</button>

                {/* 不推荐这种写法 */}
                {/* 注意这里绑定事件回调的时候函数名后面不要加括号，加了后它会自执行 */}
                <button onClick={this.handleClick2}>add2</button>
                {/* 这里更换this绑定(让handleClick2函数中的this指向和外面的this保持一致)，就可以获取到this了 => this.handleClick2.bind(this) */}

                {/* 比较推荐 */}
                <button onClick={this.handleClick3} >add3</button>

                {/* 非常推荐 => 传参很方便！ */}
                <button onClick={() => this.handleClick4()}>add4</button>
            </div>
        )
    }

    handleClick2() {
        console.log('click2', this); // 这里打印的this是 undefined
    }

    handleClick3 = (evt) => {
        console.log('click3', this.a); // 这里this指向 App 的实例，这里可以正常访问
        console.log('事件对象:', evt, '事件源目标', evt.target); // 事件源目标是根节点
    }

    handleClick4 = () => {
        console.log('click4', this.a); // 这里不写成箭头函数也可以正常访问到 this(App组件实例)
    }
}

/**
 * 改变this指向的三个函数
 *  call => 改变this指向并自动执行函数
 *  apply => 改变this指向并自动执行函数
 *  bind => 改变this指向 需要手动加括号执行函数
 */

let obj1 = {
    name: 'obj1',
    getName() {
        console.log(this.name);
    }
}

let obj2 = {
    name: 'obj2',
    getName() {
        console.log(this.name);
    }
}

// obj1.getName()  // obj1
// obj2.getName()  // obj2
obj1.getName.call(obj2) // obj2 => 通过 call 方法改变了 this指向
obj1.getName.apply(obj2) // obj2 => 通过 apply 方法改变了 this指向
obj1.getName.bind(obj2)() // obj2 => 通过 bind 方法改变了 this 指向，并手动执行函数



//#region
// let obtn = document.getElementById('btn')
// obtn.onclick = function () {
//     console.log(this);
// }
//#endregion



// class A {
//     constructor() {
//         this.a = 111
//         this.b = 222
//     }

//     // ES7中 类中的属性可以定义在这里
//     c = 333

//     aaa() { }

//     bbb() {
//         this.ccc()
//     }

//     ccc() { }

//     ddd = () => { }

// }
// console.log(A);
